package com.yitiao.config;

import com.yitiao.service.UsersService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.annotation.Resource;
import javax.sql.DataSource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UsersService usersService;

    //注入数据源
    @Resource
    private DataSource dataSource;
    //配置对象
    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
//        jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling().accessDeniedPage("/unauth.html");
        http.logout().logoutUrl("/logout")
                .logoutSuccessUrl("/user/logout") // 发送 get 请求
                .permitAll();
        http.formLogin()
                .loginPage("/login.html") // 表单登录
                .loginProcessingUrl("/user/login") // 设置哪个是登录的 url。
                // defaultSuccessUrl 和 successForwardUrl(发的是post 请求)
                .defaultSuccessUrl("/success.html") // 登录成功之后跳转到哪个 url
                .failureForwardUrl("/fail").permitAll()
                .and()
                .authorizeRequests() // 认证配置
                .antMatchers("/health/info", "/user/login").permitAll() // 指定 URL 无需保护。
//                .antMatchers("/menu/system").hasAuthority("menu:system")  // 为指定接口配置权限
//                .antMatchers("/menu/user").hasAnyAuthority("menu:user") // 配置方式过于笨重
                .anyRequest().authenticated() // 其他请求需要认证
                .and()
                .rememberMe().tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(60)  // 有效时长 60秒
                .userDetailsService(usersService)
                .and()
                .csrf().disable();
    }

    // 注入 PasswordEncoder 类到 spring 容器中
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
